﻿using System;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Web.UI;
using System.Data;
using System.Web;
using System.Linq;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Text;

namespace CodeArt.SharePoint.Controls
{

    using System.Security.Permissions;
    using Microsoft.SharePoint.Security;
    using CodeArt.SharePoint.Library;
    using CodeArt.SharePoint.Configuration;

    [XmlRoot(Namespace = "CodeArt.SharePoint.Controls"),
    ToolboxData("<{0}:PickerSearch runat=server></{0}:PickerSearch>"),
    DefaultProperty("CommaSeparatedPickers")]
    [ValidationProperty("CommaSeparatedPickers"), SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)] 
    public class PickerSearch : EntityEditorWithPicker
    {
        private static char[] s_CommaSeparator = new char[] { ',' };
        private string m_commaSeparatedPickersDelayedUntilOnInit;
        private bool m_onInitCalled;

        protected PickerSearchData _pickerData = null;
        protected IEnumerable<System.Data.DataRow> _currentMatches = null;

        
        public PickerSearchData PickerData
        {
            get
            {
                if (_pickerData == null && String.IsNullOrEmpty(CustomProperty) == false)
                {
                    byte[] buffer = Convert.FromBase64String(CustomProperty);
                    using (MemoryStream stream = new MemoryStream(buffer))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        _pickerData = (PickerSearchData)formatter.Deserialize(stream);
                    }
                }
                return _pickerData;
            }
            set
            {
                if (value != null)
                {
                    _pickerData = value;
                    using (MemoryStream stream = new MemoryStream())
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        formatter.Serialize(stream, value);
                        CustomProperty = Convert.ToBase64String(stream.ToArray());
                    }
                }
                else
                {
                    CustomProperty = null;
                    _pickerData = null;
                }
            }
        }

        public override void Dispose()
        {
            base.Dispose();
        }

        public PickerSearch() : base()
        {
            ValidatorEnabled = true;
            AllowTypeIn = true;
            //MultiSelect = true;

        }


        [SharePointPermission(SecurityAction.Demand, ObjectModel = true)]
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            base.PickerDialogType = typeof(PickerSearchDialog);
            this.UpdateCustomProperty();

            this.m_onInitCalled = true;
            if (!string.IsNullOrEmpty(this.m_commaSeparatedPickersDelayedUntilOnInit))
            {
                base.UpdateEntities(this.GetDepartmentsEntities(this.m_commaSeparatedPickersDelayedUntilOnInit));
                this.m_commaSeparatedPickersDelayedUntilOnInit = null;
            }
        }

        private void UpdateCustomProperty()
        {
            PickerSearchData data = new PickerSearchData(this.LookupFieldName, this.PickerTemplateName);
            PickerData = data;
        }

        internal static PickerEntity CreatePickerEntity(string itemID, string displayText,
            string lookupField, DataRow entityDataRow, PickerSearch picker)
        {

            PickerEntity entity = new PickerEntity();
            entity.Key = itemID;
            entity.DisplayText = String.IsNullOrEmpty(displayText) ?
                "Unknown record" : displayText;
            entity.Description = itemID + ";#" + displayText;

            string lkIdField = picker.PickerData.PickerTemplate.ViewFields.LookupIDField;

            entity.EntityData.Clear();
            entity.EntityData[lkIdField] = entity.Key;
            entity.EntityData[lookupField] = entity.DisplayText;

            if (entityDataRow != null)
            {
                foreach (ViewFieldElement vField in picker.PickerData.PickerTemplate.ViewFields.Fields)
                {
                    if (!entity.EntityData.ContainsKey(lkIdField))
                        entity.EntityData.Add(vField.Name, entityDataRow[vField.Name]);
                }

                string lpNameField = picker.PickerData.PickerTemplate.ViewFields.LookupNameField;
                if (!entity.EntityData.ContainsKey(lpNameField))
                    entity.EntityData.Add(lpNameField, entityDataRow[lpNameField]);
            }

            entity.IsResolved = true;
            return entity;
        }

        // Called for the 'Validate' button instead of 'Browse'
        // Also called upon OK button click
        public override PickerEntity ValidateEntity(PickerEntity needsValidation)
        {
            // The PickerEntity is unresolved when the user doesn't 
            // operate the picker dialog, but presses the 'Validate' button
            if (needsValidation.IsResolved)
            {
                return needsValidation; // resolved
            }
            // When this happens, the needsValidation.DisplayText property 
            // contains the text entered in the picker field.
            string fieldText = needsValidation.DisplayText;

            if (!string.IsNullOrEmpty(fieldText))
            {
                PickerDataService service = new PickerDataService(PickerData.PickerTemplate);

                string query = string.Format("{0}='{1}'", PickerData.LookupField, fieldText);
                _currentMatches = service.FindRows(query);
                switch (_currentMatches.Count<System.Data.DataRow>())
                {
                    case 0:

                        string query1 = string.Format("{0}='{1}'", PickerData.PickerTemplate.ViewFields.LookupIDField, needsValidation.Key);
                        _currentMatches = service.FindRows(query1);
                        if (_currentMatches.Count<System.Data.DataRow>() > 0)
                        {
                            System.Data.DataRow row = _currentMatches.SingleOrDefault<System.Data.DataRow>();

                            needsValidation = PickerSearch.CreatePickerEntity(
                             Convert.ToString(row[PickerData.PickerTemplate.ViewFields.LookupIDField]),
                             Convert.ToString(row[PickerData.LookupField]),
                             PickerData.LookupField, row, this);
                        }
                        else
                        {
                            needsValidation.Description = "No match";
                        }
                        break;
                    case 1:

                        DataRow row1 = _currentMatches.SingleOrDefault<DataRow>();

                        needsValidation = PickerSearch.CreatePickerEntity(
                            Convert.ToString(row1[PickerData.PickerTemplate.ViewFields.LookupIDField]),
                            Convert.ToString(row1[PickerData.LookupField]),
                            PickerData.LookupField, row1, this);
                        break;

                    default:
                        needsValidation.Description = "Multiple matches";
                        break;
                }
            }

            return needsValidation;
        }
    
        // Called when ValidateEntity returns an unresolved item
        protected override PickerEntity[] ResolveErrorBySearch(string unresolvedText)
        {
            PickerDataService service = new PickerDataService(PickerData.PickerTemplate);
            List<PickerEntity> resolvedItems = null;
            string query = String.Format(@"{0}='{1}'", PickerData.LookupField, unresolvedText);

            _currentMatches = service.FindRows(query);

            if (String.IsNullOrEmpty(unresolvedText) == false )
            {
                if (_currentMatches.Count<DataRow>() > 0)
                {
                    resolvedItems = ConvertToPickerEntity(_currentMatches);
                }
                else
                {
                    string query1 = String.Format(@"{0}='{1}'", PickerData.PickerTemplate.ViewFields.LookupIDField, unresolvedText);


                    _currentMatches = service.FindRows(query1);

                    resolvedItems = ConvertToPickerEntity(_currentMatches);       
                }
            }
            return resolvedItems != null ?
                resolvedItems.ToArray() : null;
        }

        protected List<PickerEntity> ConvertToPickerEntity(IEnumerable<DataRow> currentMatches)
        {
            List<PickerEntity> resolvedItems = new List<PickerEntity>();
            foreach (DataRow listItem in currentMatches)
            {
                PickerEntity entity =
                    PickerSearch.CreatePickerEntity(
                    Convert.ToString(listItem[PickerData.PickerTemplate.ViewFields.LookupIDField]),
                    Convert.ToString(listItem[PickerData.LookupField]),
                    PickerData.LookupField, listItem, this);
                resolvedItems.Add(entity);
            }
            return resolvedItems;
        }

        private void SetFieldValue(ArrayList entities, string value)
        { 
            string c1 = value;
            if (!string.IsNullOrEmpty(c1))
            {
                PickerEntity entity = null;
                string[] tags = c1.Split(new string[] { ";#" }, StringSplitOptions.None);
                if (tags.Length > 1)
                {
                    entity = CreatePickerEntity(tags[0], tags[1],
                        PickerData.LookupField, null, this);
                }
                else
                {
                    entity = CreatePickerEntity(c1, c1, PickerData.LookupField, null, this);
                }  
                entities.Add(entity);
            }
        }
        public string LookupFieldName
        {
            get
            {
                string field = string.Empty;
                object obj = this.ViewState["_LookupFieldName"];
                if (obj != null)
                {
                    field = Convert.ToString(obj);
                }
                return field;
            }
            set
            {
                this.ViewState["_LookupFieldName"] = value;
            }
        }

        public string PickerTemplateName
        {
            get
            {
                string field = string.Empty;
                object obj = this.ViewState["_PickerTemplateName"];
                if (obj != null)
                {
                    field = Convert.ToString(obj);
                }
                return field;
            }
            set
            {
                this.ViewState["_PickerTemplateName"] = value;
            }
        }


        public string CommaSeparatedPickers
        {
            get
            {
                return this.GetResolvedEntityPickers();
            }
            set
            {
                if (this.m_onInitCalled)
                {
                    base.UpdateEntities(this.GetDepartmentsEntities(value));
                }
                else
                {
                    this.m_commaSeparatedPickersDelayedUntilOnInit = value;
                }
            }
        }

        private string GetResolvedEntityPickers()
        {
            ArrayList resolvedEntities = base.ResolvedEntities;
            new ArrayList(resolvedEntities.Count);
            StringBuilder builder = new StringBuilder(100);

            IEnumerator enumerator = resolvedEntities.GetEnumerator();           
            PickerEntity current;
            while (enumerator.MoveNext())
            {
                current = (PickerEntity)enumerator.Current;
                if (builder.Length <= 0)
                {
                    builder.Append(current.Key+";#"+current.DisplayText);
                }
                else
                {
                    builder.Append(",");
                    builder.Append(current.Key + ";#" + current.DisplayText);
                }
            }
            return builder.ToString();
        }


        private ArrayList GetDepartmentsEntities(string commaSeparatedAccounts)
        {
            ArrayList list = new ArrayList();
            if (commaSeparatedAccounts != null)
            {
                foreach (string str in commaSeparatedAccounts.Split(s_CommaSeparator, StringSplitOptions.RemoveEmptyEntries))
                {
                    string str2 = str.Trim();
                    if (!string.IsNullOrEmpty(str2))
                    {
                        SetFieldValue(list, str2);
                    }
                }
            }
            return list;
        }

 

 

 

 

    }
}
